├── .gitignore ├── docs ├── extra-styles.css ├── favicon.ico ├── triangle-closed.png ├── triangle-opened.png ├── bootstrap │ ├── img │ │ ├── glyphicons-halflings.png │ │ └── glyphicons-halflings-white.png │ ├── css │ │ ├── bootstrap-select.min.css │ │ ├── bootstrap-responsive.min.css │ │ └── bootstrap-responsive.css │ └── js │ │ ├── bootstrap-select.min.js │ │ └── bootstrap.min.js ├── nav.js ├── highlighter.css ├── highlighter.js ├── 404.html ├── index.html ├── haxe-nav.css ├── benched │ ├── Benched.html │ └── BenchmarkResults.html ├── index.js └── styles.css ├── samples.hxml ├── dox.hxml ├── haxelib.json ├── CHANGELOG.md ├── samples └── Fib.hx ├── README.md ├── src └── benched │ ├── BenchmarkResults.hx │ └── Benched.hx └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | *.hxs -------------------------------------------------------------------------------- /docs/extra-styles.css: -------------------------------------------------------------------------------- 1 | /** to be overridden in sub-themes */ -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/benched/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /docs/triangle-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/benched/HEAD/docs/triangle-closed.png -------------------------------------------------------------------------------- /docs/triangle-opened.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/benched/HEAD/docs/triangle-opened.png -------------------------------------------------------------------------------- /samples.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -cp samples 3 | -dce full 4 | -main Fib 5 | --js bin/fib.js 6 | -lib hxnodejs 7 | --cmd node bin/fib.js -------------------------------------------------------------------------------- /docs/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/benched/HEAD/docs/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hamaluik/benched/HEAD/docs/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /dox.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | 3 | benched.Benched 4 | benched.BenchmarkResults 5 | 6 | -D doc-gen 7 | -xml docs/dox.xml 8 | 9 | --next 10 | -cmd haxelib run dox -i docs -o docs --title "Benched" --toplevel-package "benched" -D version "0.2.0" -D source-path "https://github.com/hamaluik/benched/tree/master/src" -D description "A statistics-based benchmarking tool for Haxe, inspired by criterion" -------------------------------------------------------------------------------- /docs/nav.js: -------------------------------------------------------------------------------- 1 | var navContent=''; -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benched", 3 | "url" : "https://github.com/hamaluik/benched", 4 | "license": "Apache", 5 | "classPath": "src", 6 | "tags": ["cross", "utility"], 7 | "description": "A statistics-based benchmarking tool for Haxe, inspired by criterion", 8 | "version": "0.2.0", 9 | "releasenote": "Better output formatting, especially for changes", 10 | "contributors": ["hamaluik"], 11 | "dependencies": {} 12 | } 13 | -------------------------------------------------------------------------------- /docs/highlighter.css: -------------------------------------------------------------------------------- 1 | /** 2 | Code Highlighting 3 | **/ 4 | html pre, html pre code { 5 | font-family: consolas, monospace; 6 | white-space: pre; 7 | overflow-x: auto; 8 | } 9 | code { 10 | color: #333; 11 | } 12 | code a { 13 | color: #08c; 14 | } 15 | pre { 16 | color: #333; 17 | margin: 15px 0; 18 | padding: 0.5em; 19 | } 20 | pre .type { 21 | color: #0086b3; 22 | } 23 | pre .kwd { 24 | color: #00a; 25 | } 26 | pre .val { 27 | color: #44a; 28 | } 29 | pre .str, div.pre .str, pre .str .kwd, pre .str .val, pre .str .type { 30 | color: #a00; 31 | } 32 | pre .cmt { 33 | color: #008800; 34 | color: #998; 35 | font-style: italic; 36 | } 37 | /* Make sure keywords inside comments are not highlighted*/ 38 | pre .cmt .kwd, pre .cmt .str, pre .cmt .val, pre .cmt .type { 39 | color: #998; 40 | } 41 | .last-modified { 42 | color:#999; 43 | } 44 | .semantic { 45 | display:none; 46 | } 47 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [0.2.0]—2020-02-18 8 | ### Added 9 | - Added a function (`percentDifference`) to `BenchmarkResults` to calculate percent 10 | differences between result sets 11 | - Made `floatToStringPrecision` and `displayEng` functions in `BenchmarkResults` 12 | public if you want to use them for whatever reason 13 | 14 | ### Changed 15 | - Changed formatting of markdown tables in reports to be more well-formatted 16 | - Tidied up the `Fib` sample a bit to be more consistent between README and implementation 17 | 18 | ## [0.1.0]—2020-02-16 19 | - Initial release 20 | 21 | [Unreleased]: https://github.com/hamaluik/headbutt/compare/v0.6.0...HEAD 22 | [0.2.0]: https://github.com/hamaluik/headbutt/compare/v0.1.0...v0.2.0 23 | [0.1.0]: https://github.com/hamaluik/headbutt/releases/tag/v0.1.0 24 | -------------------------------------------------------------------------------- /docs/highlighter.js: -------------------------------------------------------------------------------- 1 | // highlighter adapted/modified from code.haxe.org 2 | (function (console) { "use strict"; 3 | var EReg = function(r,opt) { 4 | opt = opt.split("u").join(""); 5 | this.r = new RegExp(r,opt); 6 | }; 7 | EReg.prototype = { 8 | replace: function(s,by) { 9 | return s.replace(this.r,by); 10 | } 11 | }; 12 | var Highlighter = function() { }; 13 | Highlighter.main = function() { 14 | var _g = 0; 15 | var _g1 = window.document.body.querySelectorAll("pre code"); 16 | while(_g < _g1.length) { 17 | var el = _g1[_g]; 18 | ++_g; 19 | if(!Highlighter.hasClass(el,"highlighted")) { 20 | el.innerHTML = Highlighter.syntaxHighlight(el.innerHTML); 21 | el.className += " highlighted"; 22 | } 23 | } 24 | }; 25 | Highlighter.hasClass = function(el,className) { 26 | return el.className.indexOf(className) != -1; 27 | }; 28 | Highlighter.syntaxHighlight = function(html) { 29 | var kwds = ["abstract","trace","break","case","cast","class","continue","default","do","dynamic","else","enum","extends","extern","for","function","if","implements","import","in","inline","interface","macro","new","override","package","private","public","return","static","switch","throw","try","typedef","untyped","using","var","while"]; 30 | var kwds1 = new EReg("\\b(" + kwds.join("|") + ")\\b","g"); 31 | var vals = ["null","true","false","this"]; 32 | var vals1 = new EReg("\\b(" + vals.join("|") + ")\\b","g"); 33 | var types = new EReg("\\b([A-Z][a-zA-Z0-9]*)\\b","g"); 34 | html = kwds1.replace(html,"$1"); 35 | html = vals1.replace(html,"$1"); 36 | html = types.replace(html,"$1"); 37 | html = new EReg("(\"[^\"]*\")","g").replace(html,"$1"); 38 | html = new EReg("(//.+?)(\n|$)","g").replace(html,"$1$2"); 39 | html = new EReg("(/\\*\\*?(.|\n)+?\\*?\\*/)","g").replace(html,"$1"); 40 | return html; 41 | }; 42 | Highlighter.main(); 43 | })(typeof console != "undefined" ? console : {log:function(){}}); 44 | -------------------------------------------------------------------------------- /samples/Fib.hx: -------------------------------------------------------------------------------- 1 | import haxe.Unserializer; 2 | import haxe.Serializer; 3 | import benched.Benched; 4 | 5 | class Fib { 6 | static function fibonacci_naive(n: Int): Int { 7 | return switch n { 8 | case 0: 1; 9 | case 1: 1; 10 | case n: fibonacci_naive(n - 1) + fibonacci_naive(n - 2); 11 | } 12 | } 13 | 14 | static function fibonacci_optimized(n: Int): Int { 15 | var a: Int = 0; 16 | var b: Int = 1; 17 | 18 | return switch(n) { 19 | case 0: b; 20 | case _: { 21 | for(_ in 0...n) { 22 | var c = a + b; 23 | a = b; 24 | b = c; 25 | } 26 | b; 27 | } 28 | } 29 | } 30 | 31 | public static function main() { 32 | // first run our naive benchmark and serialize it 33 | // let's pretend we ran this before writing `fibonacci_optimized` 34 | var bencher = new Benched(); 35 | bencher.benchmark("Fibonacci(1)", () -> fibonacci_naive(1)); 36 | bencher.benchmark("Fibonacci(5)", () -> fibonacci_naive(5)); 37 | bencher.benchmark("Fibonacci(10)", () -> fibonacci_naive(10)); 38 | var s = new Serializer(); 39 | s.serialize(bencher); 40 | sys.io.File.saveContent("_fib_naive.hxs", s.toString()); 41 | Sys.println('### Naive Implementation'); 42 | Sys.println(bencher.generateReport()); 43 | 44 | // ... some time passes ... 45 | 46 | // now we've made some changes to our fibonacci calculator (`fibonacci_optimized`) 47 | // benchmark the results 48 | var bencher = new Benched(); 49 | bencher.benchmark("Fibonacci(1)", () -> fibonacci_optimized(1)); 50 | bencher.benchmark("Fibonacci(5)", () -> fibonacci_optimized(5)); 51 | bencher.benchmark("Fibonacci(10)", () -> fibonacci_optimized(10)); 52 | Sys.println('### Optimized Implementation'); 53 | Sys.println(bencher.generateReport()); 54 | 55 | // now load our old results and see if we made things faster 56 | var oldBencher: Benched = new Unserializer(sys.io.File.getContent("_fib_naive.hxs")).unserialize(); 57 | Sys.println("### Changes"); 58 | Sys.println(bencher.generateComparisonReport(oldBencher)); 59 | } 60 | } -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | File not found - Benched

404 Page not found

Page not found, sorry.

-------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | benched - Benched

benched version 0.2.0

A statistics-based benchmarking tool for Haxe, inspired by criterion

Benched

Utility to run benchmarks and collect samples

BenchmarkResults

A collection of values representing a timing sample

-------------------------------------------------------------------------------- /docs/haxe-nav.css: -------------------------------------------------------------------------------- 1 | nav.nav { 2 | font-family: "Open Sans", sans-serif; 3 | font-size: 16px; 4 | margin:0; 5 | } 6 | 7 | nav .fa { 8 | color:#777; 9 | margin-right:5px; 10 | } 11 | 12 | body nav * {line-height:20px;} 13 | 14 | nav .navbar-inverse .navbar-inner { 15 | background:#13110f; 16 | border:0; 17 | } 18 | 19 | nav .navbar .nav { 20 | margin:0; 21 | } 22 | 23 | nav .dropdown-menu { 24 | background:#2c2722; 25 | font-size: 14px; 26 | border-radius:0px 0px 2px 2px; 27 | padding:10px 0px; 28 | border:1px solid #2c2722; 29 | margin-top:-1px; 30 | } 31 | 32 | nav .navbar .nav>li>a { 33 | padding: 14px 12px 15px 12px; 34 | color:#ccc; 35 | } 36 | 37 | nav .dropdown-menu li a { 38 | color: #b8b5b5; 39 | padding:3px 15px; 40 | } 41 | nav .divider { 42 | background-color:transparent; 43 | border-right:1px solid #39332d; 44 | margin:5px 20px 5px 10px; 45 | height:39px; 46 | } 47 | 48 | nav .dropdown-menu .divider { 49 | background-color:transparent; 50 | border:0; 51 | border-bottom:1px solid #39332d; 52 | margin:5px 0; 53 | } 54 | 55 | nav .navbar-inverse .nav .active>a, nav .navbar-inverse .nav .active>a:hover, nav .navbar-inverse .nav .active>a:focus, nav .navbar-inverse .nav li.dropdown.open>.dropdown-toggle, nav .navbar-inverse .nav li.dropdown.active>.dropdown-toggle, nav .navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle { 56 | color: #fff; 57 | background-color:transparent; 58 | background-image:none; 59 | } 60 | 61 | nav .navbar-inverse .nav .active>a:hover { 62 | background:#39332d; 63 | } 64 | 65 | nav .dropdown-menu>.active>a, nav .dropdown-menu>.active>a:hover, nav .dropdown-menu>.active>a:focus { 66 | font-weight:bold; 67 | color: #fff; 68 | background-image:none; 69 | background:#39332d; 70 | } 71 | 72 | nav .dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus, nav .dropdown-submenu:hover>a, nav .dropdown-submenu:focus>a { 73 | background:#39332d; 74 | } 75 | 76 | nav .navbar .nav>li>.dropdown-menu:after { 77 | border-bottom-color:#2c2722; 78 | } 79 | 80 | /** MEDIA Q **/ 81 | 82 | @media (max-width: 979px) 83 | { 84 | nav .navbar-fixed-top .navbar-inner, nav .navbar-fixed-bottom .navbar-inner { 85 | padding: 0px; 86 | } 87 | nav .navbar-fixed-top { 88 | margin-bottom: 0; 89 | } 90 | } 91 | 92 | /** SUB BRAND LOGOS **/ 93 | 94 | .navbar .brand.haxe-logo { padding-right:0; margin: 3px 0 0 0px; } 95 | .navbar .brand.haxe-logo:hover { opacity:.9; } 96 | 97 | .navbar .brand.haxe-logo:after { 98 | content:" "; 99 | position:absolute; 100 | /* create arrow */ 101 | width: 0; 102 | height: 0; 103 | border-top: 22px solid transparent; 104 | border-bottom: 22px solid transparent; 105 | border-left: 7px solid #13110f; /* same color as nav bar */ 106 | top:0; 107 | } 108 | .navbar .brand.sub { 109 | background: #39332d; /* Old browsers */ 110 | background: -moz-linear-gradient(top, #39332d 50%, #2c2722 51%); /* FF3.6+ */ 111 | background: -webkit-gradient(linear, left top, left bottom, color-stop(50%,#39332d), color-stop(51%,#2c2722)); /* Chrome,Safari4+ */ 112 | background: -webkit-linear-gradient(top, #39332d 50%,#2c2722 51%); /* Chrome10+,Safari5.1+ */ 113 | background: -o-linear-gradient(top, #39332d 50%,#2c2722 51%); /* Opera 11.10+ */ 114 | background: -ms-linear-gradient(top, #39332d 50%,#2c2722 51%); /* IE10+ */ 115 | background: linear-gradient(to bottom, #39332d 50%,#2c2722 51%); /* W3C */ 116 | padding:14px 20px 13px 20px; 117 | margin:0 10px 0 0; 118 | font:bold 18px "arial black", "open sans"; 119 | line-height:22px; 120 | color:rgb(255,255,255); 121 | } 122 | .navbar .brand.sub:hover { 123 | color:rgb(230,230,230); 124 | background: #2c2722; /* Old browsers */ 125 | } 126 | 127 | .navbar .brand.sub:before { 128 | content:".."; /* two dots */ 129 | position:absolute; 130 | margin-left:-33px; 131 | margin-top:-28px; 132 | line-height:0px; 133 | font:bold 40px "Open Sans", sans-serif; 134 | letter-spacing:0px; 135 | color:#fff200; 136 | } 137 | 138 | /** SUB BRAND COLORS **/ 139 | 140 | .navbar .brand.sub.try:before { 141 | color:#f89c0e; 142 | } 143 | 144 | .navbar .brand.sub.api:before { 145 | color:#eedc16; 146 | } 147 | 148 | .navbar .brand.sub.lib:before { 149 | color:#f1471d; 150 | } 151 | .navbar .brand.sub.ide:before { 152 | color:#f89c0e; 153 | } 154 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Benched 2 | 3 | A statistics-based benchmarking tool for [Haxe](https://haxe.org/), inspired by [criterion](https://github.com/bheisler/criterion.rs). 4 | 5 | ## API 6 | 7 | [API documentation is available.](https://hamaluik.github.com/benched/) 8 | 9 | ## Sample 10 | 11 | A sample is provided in [samples/Fib.hx](samples/Fib.hx). We start by calculating 12 | the Fibonacii sequence for any given number using recursion, and benchmark the results. 13 | Note that by default, we will collect 50 samples which take at least 0.5s each to collect, 14 | meaning each benchmark will take at least 25s to run. Given that we're running 3 15 | benchmarks, each time we run this it will take about a minute and a half—be patient!. 16 | 17 | ```haxe 18 | import haxe.Serializer; 19 | import benched.Benched; 20 | 21 | class Fib { 22 | static function fibonacci(n: Int): Int { 23 | return switch n { 24 | case 0: 1; 25 | case 1: 1; 26 | case n: fibonacci(n - 1) + fibonacci(n - 2); 27 | } 28 | } 29 | 30 | public static function main() { 31 | var bencher = new Benched(); 32 | bencher.benchmark("Fibonacci(1)", () -> fibonacci(1)); 33 | bencher.benchmark("Fibonacci(5)", () -> fibonacci(5)); 34 | bencher.benchmark("Fibonacci(10)", () -> fibonacci(10)); 35 | Sys.println('### Naive Implementation'); 36 | Sys.println(bencher.generateReport()); 37 | 38 | // save the results for later 39 | var s = new Serializer(); 40 | s.serialize(bencher); 41 | sys.io.File.saveContent("_fib_naive.hxs", s.toString()); 42 | } 43 | } 44 | ``` 45 | 46 | This generates the following table: 47 | 48 | ### Naive Implementation 49 | | Benchmark | Mean Time / Iteration | 50 | |:--------------|------------------------------:| 51 | | Fibonacci(1) | `890.845 [ps] ± 106.758 [ps]` | 52 | | Fibonacci(5) | ` 71.964 [ns] ± 5.057 [ns]` | 53 | | Fibonacci(10) | `838.539 [ns] ± 18.815 [ns]` | 54 | 55 | We notice this takes a bit of time, so we re-write the fibonacci function to not 56 | be recursive and hopefully faster: 57 | 58 | ```haxe 59 | import haxe.Unserializer; 60 | import haxe.Serializer; 61 | import benched.Benched; 62 | 63 | class Fib { 64 | static function fibonacci(n: Int): Int { 65 | var a: Int = 0; 66 | var b: Int = 1; 67 | 68 | return switch(n) { 69 | case 0: b; 70 | case _: { 71 | for(_ in 0...n) { 72 | var c = a + b; 73 | a = b; 74 | b = c; 75 | } 76 | b; 77 | } 78 | } 79 | } 80 | 81 | public static function main() { 82 | // now we've made some changes to our fibonacci calculator 83 | // benchmark the results 84 | var bencher = new Benched(); 85 | bencher.benchmark("Fibonacci(1)", () -> fibonacci_naive(1)); 86 | bencher.benchmark("Fibonacci(5)", () -> fibonacci_naive(5)); 87 | bencher.benchmark("Fibonacci(10)", () -> fibonacci_naive(10)); 88 | Sys.println('### Optimized Implementation'); 89 | Sys.println(bencher.generateReport()); 90 | 91 | // now load our old results and see if we made things faster 92 | var oldBencher: Benched = new Unserializer(sys.io.File.getContent("_fib_naive.hxs")).unserialize(); 93 | Sys.println("### Changes"); 94 | Sys.println(bencher.generateComparisonReport(oldBencher)); 95 | } 96 | } 97 | ``` 98 | 99 | This results in the following tables, showing that we've sped things up considerably! 100 | 101 | ### Optimized Implementation 102 | | Benchmark | Mean Time / Iteration | 103 | |:--------------|------------------------------:| 104 | | Fibonacci(1) | ` 5.697 [ns] ± 300.938 [ps]` | 105 | | Fibonacci(5) | ` 9.700 [ns] ± 192.220 [ps]` | 106 | | Fibonacci(10) | ` 14.575 [ns] ± 355.798 [ps]` | 107 | 108 | ### Changes 109 | | Benchmark | Mean Time / Iteration | Old Mean Time / Iteration | Change | Performance Difference | 110 | |:--------------|------------------------------:|------------------------------:|:-----------------|-----------------------:| 111 | | Fibonacci(1) | ` 5.697 [ns] ± 300.938 [ps]` | `890.845 [ps] ± 106.758 [ps]` | ~6.4× **Slower** | +539.5% | 112 | | Fibonacci(5) | ` 9.700 [ns] ± 192.220 [ps]` | ` 71.964 [ns] ± 5.057 [ns]` | ~7.4× _Faster_ | -86.5% | 113 | | Fibonacci(10) | ` 14.575 [ns] ± 355.798 [ps]` | `838.539 [ns] ± 18.815 [ns]` | ~57.5× _Faster_ | -98.3% | 114 | -------------------------------------------------------------------------------- /docs/bootstrap/css/bootstrap-select.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/) 3 | * 4 | * Copyright 2013-2014 bootstrap-select 5 | * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE) 6 | */.bootstrap-select{width:220px \0}.bootstrap-select>.btn{width:100%;padding-right:25px}.error .bootstrap-select .btn{border:1px solid #b94a48}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .btn:focus{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none}.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.btn-group.dropdown-menu-right,.bootstrap-select.btn-group[class*=col-].dropdown-menu-right,.row-fluid .bootstrap-select.btn-group[class*=col-].dropdown-menu-right{float:right}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group,.form-group .bootstrap-select.btn-group{margin-bottom:0}.form-group-lg .bootstrap-select.btn-group.form-control,.form-group-sm .bootstrap-select.btn-group.form-control{padding:0}.form-inline .bootstrap-select.btn-group .form-control{width:100%}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select.btn-group>.disabled{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:0!important}.bootstrap-select.btn-group .btn .filter-option{display:inline-block;overflow:hidden;width:100%;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group[class*=col-] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;z-index:1035;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled) a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled) a small{color:#64b1d8;color:rgba(100,177,216,.4)}.bootstrap-select.btn-group .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select.btn-group .dropdown-menu li a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select.btn-group .dropdown-menu li a span.check-mark{display:none}.bootstrap-select.btn-group .dropdown-menu li a span.text{display:inline-block}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a span.check-mark{position:absolute;display:inline-block;right:15px;margin-top:5px}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.show-menu-arrow.open>.btn{z-index:1035+1}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom-width:7px;border-bottom-style:solid;border-bottom-color:#ccc;border-bottom-color:rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-bottom:0;border-top-width:7px;border-top-style:solid;border-top-color:#ccc;border-top-color:rgba(204,204,204,.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bs-searchbox,.bs-actionsbox{padding:4px 8px}.bs-actionsbox{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox input.form-control{margin-bottom:0;width:100%}.mobile-device{position:absolute;top:0;left:0;display:block!important;width:100%;height:100%!important;opacity:0} -------------------------------------------------------------------------------- /docs/benched/Benched.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | benched.Benched - Benched

Utility to run benchmarks and collect samples

Constructor

@:value({ verbose : false, samplesPerBenchmark : 50, minSecondsPerSample : 0.5 })new (minSecondsPerSample:Float = 0.5, samplesPerBenchmark:Int = 50, verbose:Bool = false)

Create a new benchmark suite

Parameters:

minSecondsPerSample

how much time must accumulate by repeating the benchmark until a sample is counted

samplesPerBenchmark

how many samples to collect per benchmark

verbose

whether or not to print progress information

Methods

benchmark (name:String, f:Void ‑> Void):BenchmarkResults

Benchmark the function f, storing the results to be processed later. 10 | Note: f should be as pure as possible, because it will be run 11 | numerous times so as to collect enough sampling data

Parameters:

name

the name of the benchmark

f

a callback to benchmark with

Returns:

BenchmarkResults

generateComparisonReport (old:Benched):String

If you change your code and generate a new benchmark, use this to compare the changes to see if the changes had 12 | a statistically significant effect. Generally this is done by serializing a Benched instance, changing the code, 13 | re-running benchmarks, and then deserializing the old benchmarks, and supplying them to this function. This generates 14 | a Markdown table similar to generateReport() 15 | but with more columns of details.

Parameters:

old

The previous run of the same benchmarks, with possibly different implementations

Returns:

String

generateReport ():String

Generate a Markdown table of all the benchmarked results

Returns:

String

-------------------------------------------------------------------------------- /src/benched/BenchmarkResults.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Apache License, Version 2.0 3 | * 4 | * Copyright (c) 2020 Kenton Hamaluik 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at: 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package benched; 18 | 19 | using Lambda; 20 | 21 | /** 22 | A collection of values representing a timing sample 23 | **/ 24 | @:forward 25 | @:allow(benched.Benched) 26 | abstract BenchmarkResults(Array) { 27 | /** 28 | The mean of the sample 29 | **/ 30 | public var mean(get, never): Float; 31 | 32 | /** 33 | The standard distribution of the sample 34 | **/ 35 | public var std(get, never): Float; 36 | 37 | /** 38 | The variance of the sample 39 | **/ 40 | public var variance(get, never): Float; 41 | 42 | /** 43 | Create a new result, which is a list of timings in seconds 44 | @param results 45 | **/ 46 | function new(results: Array) { 47 | this = results; 48 | } 49 | 50 | /** 51 | Calculate whether the means of the two results are statistically different 52 | with `α = 0.05` (`p = 0.95`). Returns `true` if the means are statistically 53 | different 54 | @param other the other result to compare against. 55 | @return Bool 56 | **/ 57 | public function isMeanDifferent(other: BenchmarkResults): Bool { 58 | // calculate t-statistic 59 | var df: Int = this.length + other.length - 2; 60 | var sw: Float = Math.sqrt(((this.length - 1) * variance + (other.length - 1) * other.variance) / df); 61 | var se: Float = sw * Math.sqrt((1 / this.length) + (1 / other.length)); 62 | var t: Float = Math.abs(mean - other.mean) / se; 63 | 64 | // 2-tailed with alpha = 0.05 65 | var table: Array = [Math.NaN, 12.7065, 4.3026, 3.1824, 2.7764, 2.5706, 2.4469, 2.3646, 2.3060, 2.2621, 2.2282, 2.2010, 2.1788, 2.1604, 2.1448, 2.1314, 2.1199, 2.1098, 2.1009, 2.0930, 2.0860, 2.0796, 2.0739, 2.0686, 2.0639, 2.0596, 2.0555, 2.0518, 2.0484, 2.0452, 2.0423, 2.0395, 2.0369, 2.0345, 2.0322, 2.0301, 2.0281, 2.0262, 2.0244, 2.0227, 2.0211, 2.0196, 2.0181, 2.0167, 2.0154, 2.0141, 2.0129, 2.0117, 2.0106, 2.0096, 2.0086, 2.0076, 2.0066, 2.0057, 2.0049, 2.0041, 2.0032, 2.0025, 2.0017, 2.0010, 2.0003, 1.9996, 1.9990, 1.9983, 1.9977, 1.9971, 1.9966, 1.9960, 1.9955, 1.9950, 1.9944, 1.9939, 1.9935, 1.9930, 1.9925, 1.9921, 1.9917, 1.9913, 1.9909, 1.9904, 1.9901, 1.9897, 1.9893, 1.9889, 1.9886, 1.9883, 1.9879, 1.9876, 1.9873, 1.9870, 1.9867, 1.9864, 1.9861, 1.9858, 1.9855, 1.9852, 1.9850, 1.9847, 1.9845, 1.9842, 1.9840, 1.9837, 1.9835, 1.9833, 1.9830, 1.9828, 1.9826, 1.9824, 1.9822, 1.9820, 1.9818, 1.9816, 1.9814, 1.9812, 1.9810, 1.9808, 1.9806, 1.9805, 1.9803, 1.9801, 1.9799, 1.9798, 1.9796, 1.9794, 1.9793, 1.9791, 1.9790, 1.9788, 1.9787, 1.9785, 1.9784, 1.9782, 1.9781, 1.9779, 1.9778, 1.9777, 1.9776, 1.9774, 1.9773, 1.9772, 1.9771, 1.9769, 1.9768, 1.9767, 1.9766, 1.9765, 1.9764, 1.9762, 1.9761, 1.9760, 1.9759, 1.9758, 1.9757, 1.9756, 1.9755, 1.9754, 1.9753, 1.9752, 1.9751, 1.9750, 1.9749, 1.9748, 1.9747, 1.9746, 1.9745, 1.9744, 1.9744, 1.9743, 1.9742, 1.9741, 1.9740, 1.9739, 1.9739, 1.9738, 1.9737, 1.9736, 1.9735, 1.9735, 1.9734, 1.9733, 1.9732, 1.9731, 1.9731, 1.9730, 1.9729, 1.9729, 1.9728, 1.9727, 1.9727, 1.9726, 1.9725, 1.9725, 1.9724, 1.9723, 1.9723, 1.9722, 1.9721, 1.9721, 1.9720, 1.9720, 1.9719]; 66 | // TODO: higher DoF? 67 | if(df > 200) df = 200; 68 | var t_table: Float = table[df]; 69 | return t >= t_table; 70 | } 71 | 72 | /** 73 | Calculate the % difference (0―100) between this benchmark and the other, 74 | using the other as the basis for comparison 75 | @param other the other / old benchmark to compare against 76 | @return Float 77 | **/ 78 | public function percentDifference(other: BenchmarkResults): Float { 79 | return 100.0 * (mean - other.mean) / other.mean; 80 | } 81 | 82 | function get_mean(): Float { 83 | var sum: Float = 0; 84 | for(result in this) { 85 | sum += result; 86 | } 87 | return sum / this.length; 88 | } 89 | 90 | function get_std(): Float { 91 | return Math.sqrt(variance); 92 | } 93 | 94 | function get_variance(): Float { 95 | var mean: Float = mean; 96 | var sum: Float = 0; 97 | for(result in this) { 98 | sum += (result - mean) * (result - mean); 99 | } 100 | return sum / this.length; 101 | } 102 | 103 | /** 104 | Utility to convert a float to a given precision with padded 0's 105 | @param n the number to convert 106 | @param prec the number of decimal places to display 107 | @see https://stackoverflow.com/a/23785753 108 | **/ 109 | public static function floatToStringPrecision(n:Float, prec:Int){ 110 | n = Math.round(n * Math.pow(10, prec)); 111 | var str = ''+n; 112 | var len = str.length; 113 | if(len <= prec){ 114 | while(len < prec){ 115 | str = '0'+str; 116 | len++; 117 | } 118 | return '0.'+str; 119 | } 120 | else{ 121 | return str.substr(0, str.length-prec) + '.'+str.substr(str.length-prec); 122 | } 123 | } 124 | 125 | static function log10(x: Float): Float { 126 | return Math.log(x) / Math.log(10); 127 | } 128 | 129 | /** 130 | Given a number, format it in [engineering notation](https://en.wikipedia.org/wiki/Engineering_notation) 131 | @param x The number to format 132 | @param unit The base SI units of the number ("s", "g", etc) 133 | @return String 134 | **/ 135 | static function displayEng(x: Float, unit: String): String { 136 | // split into mantissa and exponent 137 | var exp: Float = Math.ffloor(log10(x)); 138 | var mant: Float = x / (Math.pow(10, exp)); 139 | 140 | // convert back to original scale 141 | var x: Float = mant * Math.pow(10.0, exp); 142 | 143 | // group exponent by factors of 1000 144 | var p: Int = Math.floor(log10(x)); 145 | var p3: Int = Math.floor(p / 3); 146 | 147 | // get root 148 | var value: Float = x / Math.pow(10, 3 * p3); 149 | var suffixes: Array = ["y", "z", "a", "f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; 150 | var suffix = suffixes[p3 + 8]; 151 | 152 | // left-pad it with non-breaking spaces so eveything lines up nicely 153 | var number: String = floatToStringPrecision(value, 3); 154 | number = StringTools.lpad(number, " ", 3 + 1 + 3); 155 | 156 | return '$number [$suffix$unit]'; 157 | } 158 | 159 | /** 160 | Display the results as the mean timing with an error, both in engineering notation 161 | @return String 162 | **/ 163 | public function toString(): String { 164 | return '${displayEng(mean, "s")} ± ${displayEng(std, "s")}'; 165 | } 166 | } -------------------------------------------------------------------------------- /docs/benched/BenchmarkResults.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | benched.BenchmarkResults - Benched

A collection of values representing a timing sample

Variables

@:implread onlymean:Float

The mean of the sample

@:implread onlystd:Float

The standard distribution of the sample

@:implread onlyvariance:Float

The variance of the sample

Methods

@:implisMeanDifferent (this:Array<Float>):Bool

Calculate whether the means of the two results are statistically different 10 | with α = 0.05 (p = 0.95). Returns true if the means are statistically 11 | different

Parameters:

other

the other result to compare against.

Returns:

Bool

@:implpercentDifference (this:Array<Float>):Float

Calculate the % difference (0―100) between this benchmark and the other, 12 | using the other as the basis for comparison

Parameters:

other

the other / old benchmark to compare against

Returns:

Float

@:impltoString ():String

Display the results as the mean timing with an error, both in engineering notation

Returns:

String

Static methods

staticfloatToStringPrecision (n:Float, prec:Int):String

Utility to convert a float to a given precision with padded 0's

Parameters:

n

the number to convert

prec

the number of decimal places to display

See:

-------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | function createCookie(name, value, days) { 2 | localStorage.setItem(name, value); 3 | } 4 | 5 | function readCookie(name) { 6 | return localStorage.getItem(name); 7 | } 8 | 9 | function toggleInherited(el) { 10 | var toggle = $(el).closest(".toggle"); 11 | toggle.toggleClass("toggle-on"); 12 | if (toggle.hasClass("toggle-on")) { 13 | $("i", toggle).removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 14 | } else { 15 | $("i", toggle).addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 16 | } 17 | return false; 18 | } 19 | 20 | function toggleCollapsed(el) { 21 | var toggle = $(el).closest(".expando"); 22 | toggle.toggleClass("expanded"); 23 | 24 | if (toggle.hasClass("expanded")) { 25 | $(toggle).find("i").first().removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 26 | } else { 27 | $(toggle).find("i").first().addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 28 | } 29 | updateTreeState(); 30 | return false; 31 | } 32 | 33 | function updateTreeState(){ 34 | var states = []; 35 | $("#nav .expando").each(function(i, e){ 36 | states.push($(e).hasClass("expanded") ? 1 : 0); 37 | }); 38 | var treeState = JSON.stringify(states); 39 | createCookie("treeState", treeState); 40 | } 41 | 42 | var filters = {}; 43 | 44 | function selectVersion(e) { 45 | setVersion($(e.target).parent().attr("data")); 46 | } 47 | 48 | function setPlatform(platform) { 49 | createCookie("platform", platform); 50 | $("#select-platform").val(platform); 51 | 52 | var styles = ".platform { display:none }"; 53 | var platforms = dox.platforms; 54 | if (platform == "flash" || platform == "js") { 55 | styles += ".package-sys { display:none; } "; 56 | } 57 | for (var i = 0; i < platforms.length; i++) { 58 | var p = platforms[i]; 59 | if (platform == "sys") { 60 | if (p != "flash" && p != "js") { 61 | styles += ".platform-" + p + " { display:inherit } "; 62 | } 63 | } 64 | else 65 | { 66 | if (platform == "all" || p == platform) { 67 | styles += ".platform-" + p + " { display:inherit } "; 68 | } 69 | } 70 | } 71 | 72 | if (platform != "flash" && platform != "js") { 73 | styles += ".platform-sys { display:inherit } "; 74 | } 75 | 76 | $("#dynamicStylesheet").text(styles); 77 | } 78 | /* 79 | function setVersion(version) { 80 | createCookie("version", version); 81 | } 82 | */ 83 | 84 | $(document).ready(function(){ 85 | $("#nav").html(navContent); 86 | var treeState = readCookie("treeState"); 87 | 88 | $("#nav .expando").each(function(i, e){ 89 | $("i", e).first().addClass("fa-arrow-circle-right").removeClass("fa-arrow-circle-down"); 90 | }); 91 | 92 | $(".treeLink").each(function() { 93 | this.href = this.href.replace("::rootPath::", dox.rootPath); 94 | }); 95 | 96 | if (treeState != null) 97 | { 98 | var states = JSON.parse(treeState); 99 | $("#nav .expando").each(function(i, e){ 100 | if (states[i]) { 101 | $(e).addClass("expanded"); 102 | $("i", e).first().removeClass("fa-arrow-circle-right").addClass("fa-arrow-circle-down"); 103 | } 104 | }); 105 | } 106 | $("head").append(""); 107 | 108 | setPlatform(readCookie("platform") == null ? "all" : readCookie("platform")); 109 | //setVersion(readCookie("version") == null ? "3_0" : readCookie("version")); 110 | 111 | $("#search").on("input", function(e){ 112 | searchQuery(e.target.value); 113 | }); 114 | 115 | $("#select-platform").selectpicker().on("change", function(e){ 116 | var value = $(":selected", this).val(); 117 | setPlatform(value); 118 | }); 119 | 120 | $("#nav a").each(function () { 121 | if (this.href == location.href) { 122 | $(this.parentElement).addClass("active"); 123 | } 124 | }); 125 | 126 | $("a.expand-button").click(function (e) { 127 | var container = $(this).parent().next(); 128 | container.toggle(); 129 | $("i", this).removeClass("fa-arrow-circle-down") 130 | .removeClass("fa-arrow-circle-right") 131 | .addClass(container.is(":visible") ? "fa-arrow-circle-down" : "fa-arrow-circle-right"); 132 | return false; 133 | }); 134 | 135 | // Because there is no CSS parent selector 136 | $("code.prettyprint").parents("pre").addClass("example"); 137 | }); 138 | 139 | function searchQuery(query) { 140 | $("#searchForm").removeAttr("action"); 141 | query = query.replace(/[&<>"']/g, ""); 142 | if (!query || query.length<2) { 143 | $("#nav").removeClass("searching"); 144 | $("#nav li").each(function(index, element){ 145 | var e = $(element); 146 | e.css("display", ""); 147 | }); 148 | $("#nav ul:first-child").css("display", "block"); 149 | $("#search-results-list").css("display", "none"); 150 | return; 151 | } 152 | var queryParts = query.toLowerCase().split(" "); 153 | var listItems = []; 154 | var bestMatch = 200; 155 | $("#nav").addClass("searching"); 156 | $("#nav ul:first-child").css("display","none"); 157 | $("#nav li").each(function(index, element) { 158 | var e = $(element); 159 | if (!e.hasClass("expando")) { 160 | var content = e.attr("data_path"); 161 | var score = searchMatch(content, queryParts); 162 | if (score >= 0) { 163 | if (score < bestMatch) { 164 | var url = dox.rootPath + e.attr("data_path").split(".").join("/") + ".html"; 165 | $("#searchForm").attr("action", url); 166 | // best match will be form action 167 | bestMatch = score; 168 | } 169 | 170 | var elLink = $("a", element); 171 | // highlight matched parts 172 | var elLinkContent = elLink.text().replace(new RegExp("(" + queryParts.join("|").split(".").join("|") + ")", "ig"), "$1"); 173 | var liStyle = (score == 0) ? ("font-weight:bold") : ""; 174 | listItems.push({score: score, item: "
  • " + elLinkContent + "
  • "}); 175 | } 176 | } 177 | }); 178 | if ($("#search-results-list").length == 0) { 179 | // append to nav 180 | $("#nav").parent().append(""); 181 | } 182 | listItems.sort(function(x, y) { return x.score - y.score; }); // put in order 183 | $("#search-results-list").css("display","block").html(listItems.map(function(x) { return x.item; }).join("")); 184 | } 185 | 186 | function match(textParts, query) { 187 | var queryParts = query.split("."); 188 | if (queryParts.length == 1) { 189 | var queryPart = queryParts[0]; 190 | for (var i = 0; i < textParts.length; ++i) { 191 | var textPart = textParts[i]; 192 | if (textPart.indexOf(queryPart) > -1) { 193 | // We don't want to match the same part twice, so let's remove it 194 | textParts[i] = textParts[i].split(queryPart).join(""); 195 | return textPart.length - queryPart.length; 196 | } 197 | } 198 | } else { 199 | var offset = -1; 200 | outer: 201 | while (true) { 202 | ++offset; 203 | if (queryParts.length + offset > textParts.length) { 204 | return -1; 205 | } 206 | var scoreSum = 0; 207 | for (var i = 0; i < queryParts.length; ++i) { 208 | var queryPart = queryParts[i]; 209 | var textPart = textParts[i + offset]; 210 | var index = textPart.indexOf(queryPart); 211 | if (index != 0) { 212 | continue outer; 213 | } 214 | scoreSum += textPart.length - queryPart.length; 215 | } 216 | return scoreSum; 217 | } 218 | } 219 | } 220 | 221 | function searchMatch(text, queryParts) { 222 | text = text.toLowerCase(); 223 | var textParts = text.split("."); 224 | var scoreSum = 0; 225 | for (var i = 0; i < queryParts.length; ++i) { 226 | var score = match(textParts, queryParts[i]); 227 | if (score == -1) { 228 | return -1; 229 | } 230 | scoreSum += score + text.length; 231 | } 232 | return scoreSum; 233 | } 234 | 235 | function errorSearch() { 236 | var errorURL = ""; 237 | if(!!window.location.pathname) { 238 | errorURL = window.location.pathname; 239 | }else if(!!window.location.href) { 240 | errorURL = window.location.href; 241 | } 242 | if(!!errorURL) { 243 | var searchTerm = errorURL.split("/").pop(); 244 | if(searchTerm.indexOf(".html") > -1) { searchTerm = searchTerm.split(".html").join(""); } 245 | if(!!searchTerm) { 246 | // update filter with search term 247 | $("#search").val(searchTerm); 248 | searchQuery(searchTerm); 249 | } 250 | } 251 | } -------------------------------------------------------------------------------- /docs/styles.css: -------------------------------------------------------------------------------- 1 | .main-content { 2 | margin-top:15px; 3 | } 4 | 5 | .dark { 6 | background: rgb(20,20,25); 7 | color: white; 8 | } 9 | .dark a { 10 | color: white; 11 | } 12 | .dark a:hover { 13 | color: rgb(200,200,200); 14 | } 15 | .dark blockquote { 16 | border-left: 3px solid rgb(126,126,129); 17 | } 18 | .dark blockquote small { 19 | color: white; 20 | font-weight: bold; 21 | } 22 | .dark blockquote small:before { 23 | display: none; 24 | } 25 | 26 | /* #nav { */ 27 | /* float: left; */ 28 | /* width: 250px; */ 29 | /* background: green; */ 30 | /* } */ 31 | /*#content .header { position:absolute; background:rgba(255,255,255,0.9); left:250px; right:15px; padding:0px 12px; border-bottom:1px solid #EEE;}*/ 32 | /*#content .body { padding-top:80px;}*/ 33 | .nav-list {padding-right: 0; } 34 | .nav-list>li>a, .nav-list .nav-header {margin-right:0;} 35 | .nav-list>li>a.treeLink {padding-left:20px;} 36 | .nav-list a { overflow: hidden; font-size:14px; text-shadow: none!important;} 37 | .nav-list>.active>a.treeLink, .nav-list>.active>a.treeLink:hover, .nav-list>.active>a.treeLink:focus { 38 | background:#999; 39 | color:#fff; 40 | } 41 | 42 | .nav-list li i.fa { 43 | height: 16px; 44 | width: 16px; 45 | color: rgb(200,200,200); 46 | font-weight:normal; 47 | font-size:16px; 48 | } 49 | 50 | .viewsource {float:right} 51 | 52 | /** Footer sitemap **/ 53 | footer{ 54 | margin-top:40px; 55 | font-size:14px; 56 | } 57 | .section.site-footer { 58 | border-bottom: 0px; 59 | } 60 | .copyright { 61 | padding: 6px; 62 | overflow: hidden; 63 | text-align:center; 64 | margin: 40px 0; 65 | } 66 | .dark .copyright a { color:#F48821; } 67 | 68 | /* .doc { margin-top:16px; } */ 69 | .toggle-hide { display:block; } 70 | .toggle-show { display:none; } 71 | .toggle-on .toggle-hide { display:none !important; } 72 | .toggle-on .toggle-show { display:block !important; } 73 | .related-types .toggle-hide { padding-top:4px; } 74 | /* .availability { margin-left:14px; color:#93a1a1; } */ 75 | /* .doc { margin-left:14px; } */ 76 | 77 | 78 | 79 | /* #nav li { list-style-type: none; } */ 80 | #nav .expando > ul { display:none; } 81 | #nav .expando.expanded > ul { display:inherit; } 82 | /* #nav ul, #nav li li { margin-left: 10px; } */ 83 | #nav img { padding-right:4px; } 84 | #nav .pack { display:none; } 85 | 86 | /* .nav .nav li { margin-left: 14px; } */ 87 | 88 | .dropdown { padding: 0 9px; } 89 | 90 | #nav.searching .expando > ul { display:inherit; } 91 | #nav.searching .expando > a { display:none; } 92 | #nav.searching ul { margin-left:0px; } 93 | #nav.searching .pack { display:inline; } 94 | #nav.searching .nav-list .nav-list { padding-left: 0; padding-right: 0; } 95 | 96 | .nav-header { 97 | text-transform: none; 98 | font-size:14px; 99 | color:#555; 100 | text-shadow: none; 101 | } 102 | 103 | .availability { 104 | color: #e48931; 105 | font-size: 90%; 106 | } 107 | 108 | h3 code { 109 | background:none; 110 | box-shadow: 0 0 15px rgb(240, 240, 240); 111 | padding: 4px 8px; 112 | white-space: inherit; 113 | display: inline-block; 114 | line-height: 1.5em; 115 | margin-left: -10px; 116 | } 117 | 118 | h3 span.label, .label-meta { 119 | margin-right: 5px; 120 | } 121 | 122 | .label.label-meta { 123 | background:#5959AC; 124 | } 125 | 126 | /* hide meta that has doesn't belong in the API (implementation details) */ 127 | .label-meta-impl, .label-meta-value, .label-meta-has_untyped, .label-meta-hlNative, .label-meta-access, .label-meta-allow, .label-meta-keep, .label-meta-keepInit, .label-meta-keepSub, .label-meta-dox, .label-meta-noCompletion, .label-meta-directlyUsed, .label-meta-build, .label-meta-autoBuild, .label-meta-genericBuild, .label-meta-analyzer, .label-meta-enum, .label-meta-extern { 128 | display:none; 129 | } 130 | 131 | .label-meta.label-meta-from, .label-meta.label-meta-to { 132 | background:#a93685; 133 | } 134 | 135 | .alert.alert-deprecated { 136 | font-size: 90%; 137 | margin-bottom: 10px; 138 | padding: 4px 35px 4px 14px; 139 | } 140 | 141 | code { 142 | font-family: Monaco,Menlo,Consolas,"Courier New",monospace; 143 | font-weight: normal; 144 | color: #666; 145 | background-color: #f7f7f9; 146 | border: 1px solid #e1e1e8; 147 | white-space: nowrap; 148 | border-radius: 3px; 149 | padding: 2px 4px; 150 | font-size: 13px; 151 | } 152 | 153 | code .identifier { 154 | font-family:bold 14px "Helvetica Neue",Helvetica,Arial,sans-serif; 155 | color:#002b36; 156 | padding: 0 0 0 5px; 157 | } 158 | 159 | code .identifier, code.type { 160 | font-weight: bold; 161 | } 162 | 163 | /* code { background:#FDF6E3; color:#002b36; tab-size:4; } [> light <] */ 164 | code a { text-decoration:none; } 165 | code a:hover { text-decoration:underline; } 166 | 167 | /*code.dark { background:#272822; color:#F8F8F2; border:none; } */ 168 | code .type { color:#268bd2; } 169 | /* code .keyword { color:#dc322f; } */ 170 | /* code .directive { color:#2aa198; } */ 171 | /* code .constant { color:#AE81FF; } */ 172 | /* code .comment { color:#75715E; } */ 173 | /* code .string { color:#E6DB74; } */ 174 | /* code .macro { color:#A6E22A; } */ 175 | /* code .inactive { color:#75715E; } */ 176 | 177 | /* .navbar-fixed-top { position: fixed; } */ 178 | /* .navbar-fixed-top .navbar-inner, */ 179 | /* .navbar-fixed-bottom .navbar-inner { padding: 0; } */ 180 | 181 | body { 182 | padding: 0px; 183 | font-size:16px; 184 | font-family:"Open Sans", sans-serif; 185 | color: #1e1e1e; 186 | line-height: 1.5; 187 | } 188 | 189 | h1, h2, h3, h4, h5, h6 { 190 | font-family: "Source Sans Pro", sans-serif; 191 | font-weight: 600; 192 | word-wrap: break-word; 193 | } 194 | h1 { 195 | font-size: 36px; 196 | color: #171717; 197 | } 198 | h1 small { 199 | font-size: 14px; 200 | color: #999; 201 | font-weight: normal; 202 | } 203 | h2 { 204 | font-size: 30px; 205 | } 206 | h3 { 207 | font-size: 24px; 208 | } 209 | h4 { 210 | font-size: 20px; 211 | } 212 | h5, h5 code { 213 | font-size: 18px; 214 | } 215 | h6 { 216 | font-size: 16px; 217 | } 218 | 219 | .sidebar-nav { 220 | padding: 9px 0; 221 | } 222 | 223 | #searchForm { 224 | padding: 0 9px; 225 | margin-bottom:10px; 226 | } 227 | 228 | #searchForm .control-group { 229 | margin: 0; 230 | } 231 | 232 | .indent { 233 | margin-left: 20px; 234 | border-left: 5px solid #eeeeee; 235 | padding-left:20px; 236 | } 237 | 238 | table.params { 239 | border-left: 5px solid #eeeeee; 240 | margin-left: 20px; 241 | } 242 | table.params th { 243 | background:#fcfcfc; 244 | } 245 | 246 | .doc-main { 247 | margin-bottom: 40px; 248 | } 249 | 250 | .doc-main p { font-style: italic; } 251 | 252 | .section { 253 | border-bottom: 1px solid #eee; 254 | } 255 | 256 | .table p { 257 | margin: 3px 0; 258 | } 259 | 260 | .table th, .table td { 261 | border-top: 0; 262 | border-bottom: 1px solid #ccc; 263 | } 264 | 265 | .table a small { 266 | color: #666; 267 | } 268 | 269 | .table .fa { 270 | color: rgb(200,200,200); 271 | margin-right:5px; 272 | } 273 | 274 | .javadoc { 275 | /* font-weight: normal; */ 276 | /* font-size: small; */ 277 | margin-top: 20px; 278 | font-style: italic; 279 | } 280 | .inline-content * { 281 | display: inline; 282 | } 283 | /** 284 | * Stuff for input-block-level: 285 | * http://stackoverflow.com/questions/13306670/bootstrap-prepended-and-appended-input-how-to-max-input-field-width 286 | */ 287 | .input-append.input-block-level, 288 | .input-prepend.input-block-level { 289 | display: table; 290 | } 291 | .input-append.input-block-level .add-on, 292 | .input-prepend.input-block-level .add-on { 293 | display: table-cell; 294 | } 295 | .input-append.input-block-level > input, 296 | .input-prepend.input-block-level > input { 297 | box-sizing: border-box; /* use bootstrap mixin or include vendor variants */ 298 | -moz-box-sizing: border-box; /* for Firefox */ 299 | -webkit-box-sizing: border-box; /* for Firefox */ 300 | -ms-box-sizing: border-box; /* for Firefox */ 301 | -o-box-sizing: border-box; /* for Firefox */ 302 | display: table; /* table-cell is not working well in Chrome for small widths */ 303 | min-height: inherit; 304 | width: 100%; 305 | } 306 | .input-append.input-block-level > input { 307 | border-right: 0; 308 | } 309 | .input-prepend.input-block-level > input { 310 | border-left: 0; 311 | } 312 | 313 | .field { 314 | padding-bottom: 10px; 315 | } 316 | .field + .field { 317 | border-top: 1px solid #eee; 318 | margin-top: 10px; 319 | } 320 | .fields { 321 | margin-left: 40px; 322 | } 323 | .field-source { 324 | margin-top: 15px; 325 | visibility: hidden; 326 | } 327 | .field:hover .field-source { 328 | visibility: inherit; 329 | } 330 | 331 | pre.example { 332 | position: relative; 333 | padding-top: 34.5px; 334 | } 335 | pre.example:before { 336 | position: absolute; 337 | top: -1px; 338 | left: -1px; 339 | 340 | content: "Example"; 341 | color: #999; 342 | padding: 2px 6px; 343 | background: #fff; 344 | font-weight: bold; 345 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 346 | 347 | -moz-border-radius: 4px 0; 348 | -ms-border-radius: 4px 0; 349 | -webkit-border-radius: 4px 0; 350 | border-radius: 4px 0; 351 | border: 1px solid rgba(0,0,0,0.15); 352 | } 353 | 354 | .inherited-fields { 355 | padding: 5px 20px; 356 | margin-top:1em; 357 | background:#fcfcfc; 358 | } 359 | 360 | @media (max-width: 767px) { 361 | .navbar-fixed-top, .navbar-fixed-bottom, .navbar-static-top { 362 | margin-right: 0; 363 | margin-left: 0; 364 | } 365 | .navbar .divider { 366 | display: none; 367 | } 368 | 369 | .main-content { 370 | margin-top:0px; 371 | } 372 | } 373 | @media (max-width: 979px) { 374 | .main-content { 375 | margin-top:15px; 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /src/benched/Benched.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Apache License, Version 2.0 3 | * 4 | * Copyright (c) 2020 Kenton Hamaluik 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at: 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package benched; 18 | 19 | import haxe.ds.ArraySort; 20 | import haxe.Json; 21 | import haxe.Timer; 22 | using Lambda; 23 | using StringTools; 24 | 25 | private enum TableAlignment { 26 | Left; 27 | Center; 28 | Right; 29 | } 30 | 31 | /** 32 | Utility to run benchmarks and collect samples 33 | **/ 34 | class Benched { 35 | /** 36 | How long a process must take to count as a sample. If the sample takes 37 | less time than this, it will be repeated until it this time is completed 38 | **/ 39 | var minSecondsPerSample: Float; 40 | 41 | /** 42 | How many samples we must collect from each benchmark until we are satisfied 43 | that we have a respresentative population 44 | **/ 45 | var samplesPerBenchmark: Int; 46 | 47 | /** 48 | All our benchmarks (an `Array` instead of `haxe.ds.StringMap` in order to preserve order) 49 | **/ 50 | var benchmarks: Array<{name: String, results: BenchmarkResults}>; 51 | 52 | /** 53 | Whether or not to print progress information 54 | **/ 55 | var verbose: Bool; 56 | 57 | /** 58 | Create a new benchmark suite 59 | @param minSecondsPerSample how much time must accumulate by repeating the benchmark until a sample is counted 60 | @param samplesPerBenchmark how many samples to collect per benchmark 61 | @param verbose whether or not to print progress information 62 | **/ 63 | public function new(minSecondsPerSample: Float = 0.5, samplesPerBenchmark: Int = 50, verbose: Bool = false) { 64 | this.minSecondsPerSample = minSecondsPerSample; 65 | this.samplesPerBenchmark = samplesPerBenchmark; 66 | this.verbose = verbose; 67 | this.benchmarks = []; 68 | } 69 | 70 | inline function stamp(): Float { 71 | #if (sys || hxnodejs) 72 | return Sys.cpuTime(); 73 | #else 74 | return Timer.stamp(); 75 | #end 76 | } 77 | 78 | function print(s: String): Void { 79 | #if (sys || hxnodejs) 80 | Sys.print(s); 81 | #elseif js 82 | js.html.Console.log(s); 83 | #else 84 | trace(s); 85 | #end 86 | } 87 | 88 | function println(s: String): Void { 89 | #if (sys || hxnodejs) 90 | Sys.println(s); 91 | #elseif js 92 | js.html.Console.log(s); 93 | #else 94 | trace(s); 95 | #end 96 | } 97 | 98 | /** 99 | Benchmark the function `f`, storing the results to be processed later. 100 | **Note**: `f` should be _as pure as possible_, because it will be run 101 | numerous times so as to collect enough sampling data 102 | @param name the name of the benchmark 103 | @param f a callback to benchmark with 104 | @return BenchmarkResults 105 | **/ 106 | public function benchmark(name: String, f: Void->Void): BenchmarkResults { 107 | // first determine how long it takes to acquire a sample 108 | var iterationsPerSample: Int = 0; 109 | 110 | // first test the degenerate case where the execution time is too small 111 | // to measure 112 | if(verbose) println('[Benched]($name): calculating sample iterations'); 113 | var startTime: Float = stamp(); 114 | f(); 115 | var endTime: Float = stamp(); 116 | 117 | if(endTime - startTime == 0.0) { 118 | // we can't measure the execution because the system isn't accurate 119 | // enough, so do the somewhat innacurate way of repeating a ton of times 120 | if(verbose) println('[Benched]($name): warning: degenerate case, your function is too fast!'); 121 | startTime = stamp(); 122 | do { 123 | f(); 124 | endTime = stamp(); 125 | iterationsPerSample++; 126 | } while(endTime - startTime < minSecondsPerSample); 127 | } 128 | else { 129 | // we can measure individual runs, so do that 130 | // we already took a sample, so use that to start with 131 | var runningTimer: Float = endTime - startTime; 132 | iterationsPerSample++; 133 | while(runningTimer < minSecondsPerSample) { 134 | startTime = stamp(); 135 | f(); 136 | endTime = stamp(); 137 | runningTimer += endTime - startTime; 138 | iterationsPerSample++; 139 | } 140 | } 141 | if(verbose) println('[Benched]($name): ${iterationsPerSample} iterations required to take ${minSecondsPerSample} sample'); 142 | 143 | // ok, now we know how many times we need to run in order to get a sample, 144 | // collect our samples! 145 | if(verbose) println('[Benched]($name): ${iterationsPerSample} running benchmark...'); 146 | var samples: Array = []; 147 | var printMod: Int = Std.int(samplesPerBenchmark / 10); 148 | for(i in 0...this.samplesPerBenchmark) { 149 | var startTime: Float = stamp(); 150 | for(_ in 0...iterationsPerSample) f(); 151 | var endTime: Float = stamp(); 152 | samples.push((endTime - startTime) / iterationsPerSample); 153 | if(i % printMod == 0 && verbose) print('\r[Benched]($name): ${Math.round((i + 1) / samplesPerBenchmark * 100)}%'); 154 | } 155 | if(verbose) println('\n[Benched]($name): Completed!'); 156 | 157 | // and store the result 158 | var results = new BenchmarkResults(samples); 159 | this.benchmarks.push({name: name, results: results}); 160 | return results; 161 | } 162 | 163 | static function formatTable(headers: Array, alignments: Array, rows: Array>): String { 164 | final widths: Array = headers.mapi(function(column: Int, header: String): Int { 165 | function max(a: Int, b: Int): Int { 166 | return a > b ? a : b; 167 | } 168 | return rows.map((r) -> r[column].length).fold(max, header.length); 169 | }); 170 | 171 | var table: String = ""; 172 | 173 | // first the headers 174 | for(i in 0...headers.length) { 175 | table += switch(alignments[i]) { 176 | case Left, Center: '| ${headers[i].rpad(" ", widths[i])} '; 177 | case Right: '| ${headers[i].lpad(" ", widths[i])} '; 178 | }; 179 | } 180 | table += "|\n"; 181 | 182 | // now alignments 183 | for(i in 0...alignments.length) { 184 | var leftChar: String = switch(alignments[i]) { 185 | case Left, Center: ":"; 186 | case Right: "-"; 187 | }; 188 | var rightChar: String = switch(alignments[i]) { 189 | case Left: "-"; 190 | case Right, Center: ":"; 191 | }; 192 | table += "|" + leftChar + StringTools.rpad("", "-", widths[i]) + rightChar; 193 | } 194 | table += "|\n"; 195 | 196 | // now the rows 197 | for(row in rows) { 198 | for(i in 0...row.length) { 199 | table += switch(alignments[i]) { 200 | case Left, Center: '| ${row[i].rpad(" ", widths[i])} '; 201 | case Right: '| ${row[i].lpad(" ", widths[i])} '; 202 | }; 203 | } 204 | table += "|\n"; 205 | } 206 | 207 | return table; 208 | } 209 | 210 | /** 211 | Generate a [Markdown table](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) of all the benchmarked results 212 | @return String 213 | **/ 214 | public function generateReport(): String { 215 | final benches: Array> = this.benchmarks.map((b) -> [ 216 | b.name, 217 | '`${b.results.toString()}`', 218 | ]); 219 | return formatTable( 220 | ["Benchmark", "Mean Time / Iteration"], 221 | [Left, Right], 222 | benches 223 | ); 224 | } 225 | 226 | /** 227 | If you change your code and generate a new benchmark, use this to compare the changes to see if the changes had 228 | a statistically significant effect. Generally this is done by serializing a `Benched` instance, changing the code, 229 | re-running benchmarks, and then deserializing the old benchmarks, and supplying them to this function. This generates 230 | a [Markdown table](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) similar to `generateReport()` 231 | but with more columns of details. 232 | @param old The previous run of the same benchmarks, with possibly different implementations 233 | @return String 234 | **/ 235 | public function generateComparisonReport(old: Benched): String { 236 | // first get a list of our benchmarks 237 | final benches: Array<{ 238 | name: String, 239 | results: BenchmarkResults, 240 | oldResults: Null, 241 | }> = [for(bench in this.benchmarks) { 242 | name: bench.name, 243 | results: bench.results, 244 | oldResults: { 245 | var oldResults = old.benchmarks.find((b) -> b.name == bench.name); 246 | if(oldResults == null) null; 247 | else oldResults.results; 248 | } 249 | }]; 250 | 251 | // now format them 252 | final benches: Array> = benches.map((b) -> [ 253 | b.name, 254 | '`${b.results.toString()}`', 255 | b.oldResults == null ? '—' : '`${b.oldResults.toString()}`', 256 | if(b.oldResults != null) { 257 | switch([b.results.mean < b.oldResults.mean, b.results.isMeanDifferent(b.oldResults)]) { 258 | case [true, true]: '~${BenchmarkResults.floatToStringPrecision(b.oldResults.mean / b.results.mean, 1)}× _Faster_'; 259 | case [false, true]: '~${BenchmarkResults.floatToStringPrecision(b.results.mean / b.oldResults.mean, 1)}× **Slower**'; 260 | case [_, false]: "No Change"; 261 | } 262 | } 263 | else { 264 | "—"; 265 | }, 266 | if(b.oldResults != null) { 267 | var change = b.results.percentDifference(b.oldResults); 268 | (change >= 0 ? "+" : "") + BenchmarkResults.floatToStringPrecision(change, 1) + "%"; 269 | } 270 | else { 271 | "—"; 272 | } 273 | ]); 274 | return formatTable( 275 | ["Benchmark", "Mean Time / Iteration", "Old Mean Time / Iteration", "Change", "Performance Difference"], 276 | [Left, Right, Right, Left, Right], 277 | benches 278 | ); 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /docs/bootstrap/css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2013 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /docs/bootstrap/js/bootstrap-select.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap-select v1.6.3 (http://silviomoreto.github.io/bootstrap-select/) 3 | * 4 | * Copyright 2013-2014 bootstrap-select 5 | * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE) 6 | */ 7 | !function(a){"use strict";function b(a,b){return a.toUpperCase().indexOf(b.toUpperCase())>-1}function c(b){var c=[{re:/[\xC0-\xC6]/g,ch:"A"},{re:/[\xE0-\xE6]/g,ch:"a"},{re:/[\xC8-\xCB]/g,ch:"E"},{re:/[\xE8-\xEB]/g,ch:"e"},{re:/[\xCC-\xCF]/g,ch:"I"},{re:/[\xEC-\xEF]/g,ch:"i"},{re:/[\xD2-\xD6]/g,ch:"O"},{re:/[\xF2-\xF6]/g,ch:"o"},{re:/[\xD9-\xDC]/g,ch:"U"},{re:/[\xF9-\xFC]/g,ch:"u"},{re:/[\xC7-\xE7]/g,ch:"c"},{re:/[\xD1]/g,ch:"N"},{re:/[\xF1]/g,ch:"n"}];return a.each(c,function(){b=b.replace(this.re,this.ch)}),b}function d(a){var b={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},c="(?:"+Object.keys(b).join("|")+")",d=new RegExp(c),e=new RegExp(c,"g"),f=null==a?"":""+a;return d.test(f)?f.replace(e,function(a){return b[a]}):f}function e(b,c){var d=arguments,e=b,b=d[0],c=d[1];[].shift.apply(d),"undefined"==typeof b&&(b=e);var g,h=this.each(function(){var e=a(this);if(e.is("select")){var h=e.data("selectpicker"),i="object"==typeof b&&b;if(h){if(i)for(var j in i)i.hasOwnProperty(j)&&(h.options[j]=i[j])}else{var k=a.extend({},f.DEFAULTS,a.fn.selectpicker.defaults||{},e.data(),i);e.data("selectpicker",h=new f(this,k,c))}"string"==typeof b&&(g=h[b]instanceof Function?h[b].apply(h,d):h.options[b])}});return"undefined"!=typeof g?g:h}a.expr[":"].icontains=function(c,d,e){return b(a(c).text(),e[3])},a.expr[":"].aicontains=function(c,d,e){return b(a(c).data("normalizedText")||a(c).text(),e[3])};var f=function(b,c,d){d&&(d.stopPropagation(),d.preventDefault()),this.$element=a(b),this.$newElement=null,this.$button=null,this.$menu=null,this.$lis=null,this.options=c,null===this.options.title&&(this.options.title=this.$element.attr("title")),this.val=f.prototype.val,this.render=f.prototype.render,this.refresh=f.prototype.refresh,this.setStyle=f.prototype.setStyle,this.selectAll=f.prototype.selectAll,this.deselectAll=f.prototype.deselectAll,this.destroy=f.prototype.remove,this.remove=f.prototype.remove,this.show=f.prototype.show,this.hide=f.prototype.hide,this.init()};f.VERSION="1.6.3",f.DEFAULTS={noneSelectedText:"Nothing selected",noneResultsText:"No results match",countSelectedText:function(a){return 1==a?"{0} item selected":"{0} items selected"},maxOptionsText:function(a,b){var c=[];return c[0]=1==a?"Limit reached ({n} item max)":"Limit reached ({n} items max)",c[1]=1==b?"Group limit reached ({n} item max)":"Group limit reached ({n} items max)",c},selectAllText:"Select All",deselectAllText:"Deselect All",multipleSeparator:", ",style:"btn-default",size:"auto",title:null,selectedTextFormat:"values",width:!1,container:!1,hideDisabled:!1,showSubtext:!1,showIcon:!0,showContent:!0,dropupAuto:!0,header:!1,liveSearch:!1,actionsBox:!1,iconBase:"glyphicon",tickIcon:"glyphicon-ok",maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,searchAccentInsensitive:!1},f.prototype={constructor:f,init:function(){var b=this,c=this.$element.attr("id");this.$element.hide(),this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),this.$newElement=this.createView(),this.$element.after(this.$newElement),this.$menu=this.$newElement.find("> .dropdown-menu"),this.$button=this.$newElement.find("> button"),this.$searchbox=this.$newElement.find("input"),this.options.dropdownAlignRight&&this.$menu.addClass("dropdown-menu-right"),"undefined"!=typeof c&&(this.$button.attr("data-id",c),a('label[for="'+c+'"]').click(function(a){a.preventDefault(),b.$button.focus()})),this.checkDisabled(),this.clickListener(),this.options.liveSearch&&this.liveSearchListener(),this.render(),this.liHeight(),this.setStyle(),this.setWidth(),this.options.container&&this.selectPosition(),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile()},createDropdown:function(){var b=this.multiple?" show-tick":"",c=this.$element.parent().hasClass("input-group")?" input-group-btn":"",d=this.autofocus?" autofocus":"",e=this.$element.parents().hasClass("form-group-lg")?" btn-lg":this.$element.parents().hasClass("form-group-sm")?" btn-sm":"",f=this.options.header?'
    '+this.options.header+"
    ":"",g=this.options.liveSearch?'':"",h=this.options.actionsBox?'
    ":"",i='
    ';return a(i)},createView:function(){var a=this.createDropdown(),b=this.createLi();return a.find("ul").append(b),a},reloadLi:function(){this.destroyLi();var a=this.createLi();this.$menu.find("ul").append(a)},destroyLi:function(){this.$menu.find("li").remove()},createLi:function(){var b=this,e=[],f=0,g=function(a,b,c){return""+a+""},h=function(a,e,f,g){var h=c(d(a));return''+a+''};return this.$element.find("option").each(function(){var c=a(this),d=c.attr("class")||"",i=c.attr("style"),j=c.data("content")?c.data("content"):c.html(),k="undefined"!=typeof c.data("subtext")?''+c.data("subtext")+"":"",l="undefined"!=typeof c.data("icon")?' ':"",m=c.is(":disabled")||c.parent().is(":disabled"),n=c[0].index;if(""!==l&&m&&(l=""+l+""),c.data("content")||(j=l+''+j+k+""),!b.options.hideDisabled||!m)if(c.parent().is("optgroup")&&c.data("divider")!==!0){if(0===c.index()){f+=1;var o=c.parent().attr("label"),p="undefined"!=typeof c.parent().data("subtext")?''+c.parent().data("subtext")+"":"",q=c.parent().data("icon")?' ':"";o=q+''+o+p+"",0!==n&&e.length>0&&e.push(g("",null,"divider")),e.push(g(o,null,"dropdown-header"))}e.push(g(h(j,"opt "+d,i,f),n))}else e.push(c.data("divider")===!0?g("",n,"divider"):c.data("hidden")===!0?g(h(j,d,i),n,"hide is-hidden"):g(h(j,d,i),n))}),this.multiple||0!==this.$element.find("option:selected").length||this.options.title||this.$element.find("option").eq(0).prop("selected",!0).attr("selected","selected"),a(e.join(""))},findLis:function(){return null==this.$lis&&(this.$lis=this.$menu.find("li")),this.$lis},render:function(b){var c=this;b!==!1&&this.$element.find("option").each(function(b){c.setDisabled(b,a(this).is(":disabled")||a(this).parent().is(":disabled")),c.setSelected(b,a(this).is(":selected"))}),this.tabIndex();var e=this.options.hideDisabled?":not([disabled])":"",f=this.$element.find("option:selected"+e).map(function(){var b,d=a(this),e=d.data("icon")&&c.options.showIcon?' ':"";return b=c.options.showSubtext&&d.attr("data-subtext")&&!c.multiple?' '+d.data("subtext")+"":"",d.data("content")&&c.options.showContent?d.data("content"):"undefined"!=typeof d.attr("title")?d.attr("title"):e+d.html()+b}).toArray(),g=this.multiple?f.join(this.options.multipleSeparator):f[0];if(this.multiple&&this.options.selectedTextFormat.indexOf("count")>-1){var h=this.options.selectedTextFormat.split(">");if(h.length>1&&f.length>h[1]||1==h.length&&f.length>=2){e=this.options.hideDisabled?", [disabled]":"";var i=this.$element.find("option").not('[data-divider="true"], [data-hidden="true"]'+e).length,j="function"==typeof this.options.countSelectedText?this.options.countSelectedText(f.length,i):this.options.countSelectedText;g=j.replace("{0}",f.length.toString()).replace("{1}",i.toString())}}this.options.title=this.$element.attr("title"),"static"==this.options.selectedTextFormat&&(g=this.options.title),g||(g="undefined"!=typeof this.options.title?this.options.title:this.options.noneSelectedText),this.$button.attr("title",d(g)),this.$newElement.find(".filter-option").html(g)},setStyle:function(a,b){this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|validate\[.*\]/gi,""));var c=a?a:this.options.style;"add"==b?this.$button.addClass(c):"remove"==b?this.$button.removeClass(c):(this.$button.removeClass(this.options.style),this.$button.addClass(c))},liHeight:function(){if(this.options.size!==!1){var a=this.$menu.parent().clone().find("> .dropdown-toggle").prop("autofocus",!1).end().appendTo("body"),b=a.addClass("open").find("> .dropdown-menu"),c=b.find("li").not(".divider").not(".dropdown-header").filter(":visible").children("a").outerHeight(),d=this.options.header?b.find(".popover-title").outerHeight():0,e=this.options.liveSearch?b.find(".bs-searchbox").outerHeight():0,f=this.options.actionsBox?b.find(".bs-actionsbox").outerHeight():0;a.remove(),this.$newElement.data("liHeight",c).data("headerHeight",d).data("searchHeight",e).data("actionsHeight",f)}},setSize:function(){this.findLis();var b,c,d,e=this,f=this.$menu,g=f.find(".inner"),h=this.$newElement.outerHeight(),i=this.$newElement.data("liHeight"),j=this.$newElement.data("headerHeight"),k=this.$newElement.data("searchHeight"),l=this.$newElement.data("actionsHeight"),m=this.$lis.filter(".divider").outerHeight(!0),n=parseInt(f.css("padding-top"))+parseInt(f.css("padding-bottom"))+parseInt(f.css("border-top-width"))+parseInt(f.css("border-bottom-width")),o=this.options.hideDisabled?", .disabled":"",p=a(window),q=n+parseInt(f.css("margin-top"))+parseInt(f.css("margin-bottom"))+2,r=function(){c=e.$newElement.offset().top-p.scrollTop(),d=p.height()-c-h};if(r(),this.options.header&&f.css("padding-top",0),"auto"==this.options.size){var s=function(){var a,h=e.$lis.not(".hide");r(),b=d-q,e.options.dropupAuto&&e.$newElement.toggleClass("dropup",c>d&&b-q3?3*i+q-2:0,f.css({"max-height":b+"px",overflow:"hidden","min-height":a+j+k+l+"px"}),g.css({"max-height":b-j-k-l-n+"px","overflow-y":"auto","min-height":Math.max(a-n,0)+"px"})};s(),this.$searchbox.off("input.getSize propertychange.getSize").on("input.getSize propertychange.getSize",s),a(window).off("resize.getSize").on("resize.getSize",s),a(window).off("scroll.getSize").on("scroll.getSize",s)}else if(this.options.size&&"auto"!=this.options.size&&f.find("li"+o).length>this.options.size){var t=this.$lis.not(".divider"+o).find(" > *").slice(0,this.options.size).last().parent().index(),u=this.$lis.slice(0,t+1).filter(".divider").length;b=i*this.options.size+u*m+n,e.options.dropupAuto&&this.$newElement.toggleClass("dropup",c>d&&b .dropdown-menu").css("width"),c=a.css("width","auto").find("> button").css("width");a.remove(),this.$newElement.css("width",Math.max(parseInt(b),parseInt(c))+"px")}else"fit"==this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width","").addClass("fit-width")):this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width",this.options.width)):(this.$menu.css("min-width",""),this.$newElement.css("width",""));this.$newElement.hasClass("fit-width")&&"fit"!==this.options.width&&this.$newElement.removeClass("fit-width")},selectPosition:function(){var b,c,d=this,e="
    ",f=a(e),g=function(a){f.addClass(a.attr("class").replace(/form-control/gi,"")).toggleClass("dropup",a.hasClass("dropup")),b=a.offset(),c=a.hasClass("dropup")?0:a[0].offsetHeight,f.css({top:b.top+c,left:b.left,width:a[0].offsetWidth,position:"absolute"})};this.$newElement.on("click",function(){d.isDisabled()||(g(a(this)),f.appendTo(d.options.container),f.toggleClass("open",!a(this).hasClass("open")),f.append(d.$menu))}),a(window).resize(function(){g(d.$newElement)}),a(window).on("scroll",function(){g(d.$newElement)}),a("html").on("click",function(b){a(b.target).closest(d.$newElement).length<1&&f.removeClass("open")})},setSelected:function(a,b){this.findLis(),this.$lis.filter('[data-original-index="'+a+'"]').toggleClass("selected",b)},setDisabled:function(a,b){this.findLis(),b?this.$lis.filter('[data-original-index="'+a+'"]').addClass("disabled").find("a").attr("href","#").attr("tabindex",-1):this.$lis.filter('[data-original-index="'+a+'"]').removeClass("disabled").find("a").removeAttr("href").attr("tabindex",0)},isDisabled:function(){return this.$element.is(":disabled")},checkDisabled:function(){var a=this;this.isDisabled()?this.$button.addClass("disabled").attr("tabindex",-1):(this.$button.hasClass("disabled")&&this.$button.removeClass("disabled"),-1==this.$button.attr("tabindex")&&(this.$element.data("tabindex")||this.$button.removeAttr("tabindex"))),this.$button.click(function(){return!a.isDisabled()})},tabIndex:function(){this.$element.is("[tabindex]")&&(this.$element.data("tabindex",this.$element.attr("tabindex")),this.$button.attr("tabindex",this.$element.data("tabindex")))},clickListener:function(){var b=this;this.$newElement.on("touchstart.dropdown",".dropdown-menu",function(a){a.stopPropagation()}),this.$newElement.on("click",function(){b.setSize(),b.options.liveSearch||b.multiple||setTimeout(function(){b.$menu.find(".selected a").focus()},10)}),this.$menu.on("click","li a",function(c){var d=a(this),e=d.parent().data("originalIndex"),f=b.$element.val(),g=b.$element.prop("selectedIndex");if(b.multiple&&c.stopPropagation(),c.preventDefault(),!b.isDisabled()&&!d.parent().hasClass("disabled")){var h=b.$element.find("option"),i=h.eq(e),j=i.prop("selected"),k=i.parent("optgroup"),l=b.options.maxOptions,m=k.data("maxOptions")||!1;if(b.multiple){if(i.prop("selected",!j),b.setSelected(e,!j),d.blur(),l!==!1||m!==!1){var n=l
    ');q[2]&&(r=r.replace("{var}",q[2][l>1?0:1]),s=s.replace("{var}",q[2][m>1?0:1])),i.prop("selected",!1),b.$menu.append(t),l&&n&&(t.append(a("
    "+r+"
    ")),b.$element.trigger("maxReached.bs.select")),m&&o&&(t.append(a("
    "+s+"
    ")),b.$element.trigger("maxReachedGrp.bs.select")),setTimeout(function(){b.setSelected(e,!1)},10),t.delay(750).fadeOut(300,function(){a(this).remove()})}}}else h.prop("selected",!1),i.prop("selected",!0),b.$menu.find(".selected").removeClass("selected"),b.setSelected(e,!0);b.multiple?b.options.liveSearch&&b.$searchbox.focus():b.$button.focus(),(f!=b.$element.val()&&b.multiple||g!=b.$element.prop("selectedIndex")&&!b.multiple)&&b.$element.change()}}),this.$menu.on("click","li.disabled a, .popover-title, .popover-title :not(.close)",function(a){a.target==this&&(a.preventDefault(),a.stopPropagation(),b.options.liveSearch?b.$searchbox.focus():b.$button.focus())}),this.$menu.on("click","li.divider, li.dropdown-header",function(a){a.preventDefault(),a.stopPropagation(),b.options.liveSearch?b.$searchbox.focus():b.$button.focus()}),this.$menu.on("click",".popover-title .close",function(){b.$button.focus()}),this.$searchbox.on("click",function(a){a.stopPropagation()}),this.$menu.on("click",".actions-btn",function(c){b.options.liveSearch?b.$searchbox.focus():b.$button.focus(),c.preventDefault(),c.stopPropagation(),a(this).is(".bs-select-all")?b.selectAll():b.deselectAll(),b.$element.change()}),this.$element.change(function(){b.render(!1)})},liveSearchListener:function(){var b=this,e=a('
  • ');this.$newElement.on("click.dropdown.data-api touchstart.dropdown.data-api",function(){b.$menu.find(".active").removeClass("active"),b.$searchbox.val()&&(b.$searchbox.val(""),b.$lis.not(".is-hidden").removeClass("hide"),e.parent().length&&e.remove()),b.multiple||b.$menu.find(".selected").addClass("active"),setTimeout(function(){b.$searchbox.focus()},10)}),this.$searchbox.on("click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api",function(a){a.stopPropagation()}),this.$searchbox.on("input propertychange",function(){b.$searchbox.val()?(b.options.searchAccentInsensitive?b.$lis.not(".is-hidden").removeClass("hide").find("a").not(":aicontains("+c(b.$searchbox.val())+")").parent().addClass("hide"):b.$lis.not(".is-hidden").removeClass("hide").find("a").not(":icontains("+b.$searchbox.val()+")").parent().addClass("hide"),b.$menu.find("li").filter(":visible:not(.no-results)").length?e.parent().length&&e.remove():(e.parent().length&&e.remove(),e.html(b.options.noneResultsText+' "'+d(b.$searchbox.val())+'"').show(),b.$menu.find("li").last().after(e))):(b.$lis.not(".is-hidden").removeClass("hide"),e.parent().length&&e.remove()),b.$menu.find("li.active").removeClass("active"),b.$menu.find("li").filter(":visible:not(.divider)").eq(0).addClass("active").find("a").focus(),a(this).focus()})},val:function(a){return"undefined"!=typeof a?(this.$element.val(a),this.render(),this.$element):this.$element.val()},selectAll:function(){this.findLis(),this.$lis.not(".divider").not(".disabled").not(".selected").filter(":visible").find("a").click()},deselectAll:function(){this.findLis(),this.$lis.not(".divider").not(".disabled").filter(".selected").filter(":visible").find("a").click()},keydown:function(b){var d,e,f,g,h,i,j,k,l,m=a(this),n=m.is("input")?m.parent().parent():m.parent(),o=n.data("this"),p={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"};if(o.options.liveSearch&&(n=m.parent().parent()),o.options.container&&(n=o.$menu),d=a("[role=menu] li a",n),l=o.$menu.parent().hasClass("open"),!l&&/([0-9]|[A-z])/.test(String.fromCharCode(b.keyCode))&&(o.options.container?o.$newElement.trigger("click"):(o.setSize(),o.$menu.parent().addClass("open"),l=!0),o.$searchbox.focus()),o.options.liveSearch&&(/(^9$|27)/.test(b.keyCode.toString(10))&&l&&0===o.$menu.find(".active").length&&(b.preventDefault(),o.$menu.parent().removeClass("open"),o.$button.focus()),d=a("[role=menu] li:not(.divider):not(.dropdown-header):visible",n),m.val()||/(38|40)/.test(b.keyCode.toString(10))||0===d.filter(".active").length&&(d=o.$newElement.find("li").filter(o.options.searchAccentInsensitive?":aicontains("+c(p[b.keyCode])+")":":icontains("+p[b.keyCode]+")"))),d.length){if(/(38|40)/.test(b.keyCode.toString(10)))e=d.index(d.filter(":focus")),g=d.parent(":not(.disabled):visible").first().index(),h=d.parent(":not(.disabled):visible").last().index(),f=d.eq(e).parent().nextAll(":not(.disabled):visible").eq(0).index(),i=d.eq(e).parent().prevAll(":not(.disabled):visible").eq(0).index(),j=d.eq(f).parent().prevAll(":not(.disabled):visible").eq(0).index(),o.options.liveSearch&&(d.each(function(b){a(this).is(":not(.disabled)")&&a(this).data("index",b)}),e=d.index(d.filter(".active")),g=d.filter(":not(.disabled):visible").first().data("index"),h=d.filter(":not(.disabled):visible").last().data("index"),f=d.eq(e).nextAll(":not(.disabled):visible").eq(0).data("index"),i=d.eq(e).prevAll(":not(.disabled):visible").eq(0).data("index"),j=d.eq(f).prevAll(":not(.disabled):visible").eq(0).data("index")),k=m.data("prevIndex"),38==b.keyCode&&(o.options.liveSearch&&(e-=1),e!=j&&e>i&&(e=i),g>e&&(e=g),e==k&&(e=h)),40==b.keyCode&&(o.options.liveSearch&&(e+=1),-1==e&&(e=0),e!=j&&f>e&&(e=f),e>h&&(e=h),e==k&&(e=g)),m.data("prevIndex",e),o.options.liveSearch?(b.preventDefault(),m.is(".dropdown-toggle")||(d.removeClass("active"),d.eq(e).addClass("active").find("a").focus(),m.focus())):d.eq(e).focus();else if(!m.is("input")){var q,r,s=[];d.each(function(){a(this).parent().is(":not(.disabled)")&&a.trim(a(this).text().toLowerCase()).substring(0,1)==p[b.keyCode]&&s.push(a(this).parent().index())}),q=a(document).data("keycount"),q++,a(document).data("keycount",q),r=a.trim(a(":focus").text().toLowerCase()).substring(0,1),r!=p[b.keyCode]?(q=1,a(document).data("keycount",q)):q>=s.length&&(a(document).data("keycount",0),q>s.length&&(q=1)),d.eq(s[q-1]).focus()}(/(13|32)/.test(b.keyCode.toString(10))||/(^9$)/.test(b.keyCode.toString(10))&&o.options.selectOnTab)&&l&&(/(32)/.test(b.keyCode.toString(10))||b.preventDefault(),o.options.liveSearch?/(32)/.test(b.keyCode.toString(10))||(o.$menu.find(".active a").click(),m.focus()):a(":focus").click(),a(document).data("keycount",0)),(/(^9$|27)/.test(b.keyCode.toString(10))&&l&&(o.multiple||o.options.liveSearch)||/(27)/.test(b.keyCode.toString(10))&&!l)&&(o.$menu.parent().removeClass("open"),o.$button.focus())}},mobile:function(){this.$element.addClass("mobile-device").appendTo(this.$newElement),this.options.container&&this.$menu.hide()},refresh:function(){this.$lis=null,this.reloadLi(),this.render(),this.setWidth(),this.setStyle(),this.checkDisabled(),this.liHeight()},update:function(){this.reloadLi(),this.setWidth(),this.setStyle(),this.checkDisabled(),this.liHeight()},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()}};var g=a.fn.selectpicker;a.fn.selectpicker=e,a.fn.selectpicker.Constructor=f,a.fn.selectpicker.noConflict=function(){return a.fn.selectpicker=g,this},a(document).data("keycount",0).on("keydown",".bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input",f.prototype.keydown).on("focusin.modal",".bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=menu], .bs-searchbox input",function(a){a.stopPropagation()}),a(window).on("load.bs.select.data-api",function(){a(".selectpicker").each(function(){var b=a(this);e.call(b,b.data())})})}(jQuery); 8 | //# sourceMappingURL=bootstrap-select.js.map -------------------------------------------------------------------------------- /docs/bootstrap/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2013 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('